from kit.data import Data


# todo
class Verifier:
    def __init__(self, product_path="data/产品信息.csv",
                 equip_path="data/设备信息.csv",
                 route_path="data/工艺路线.csv"):
        self.data = Data(product_path, equip_path, route_path)

    def verify(self, sol_path='data/lx_sol.csv'):
        products = self.data.products
        machines = self.data.equips
        routes = self.data.routes
        f = open(sol_path, 'r', encoding='utf-8')
        sol = dict()
        for line in f.readlines()[1:]:
            product_id, route_No, equ_name, start, duration, end = line.split(',')
            assert abs(float(end) - float(start) - float(duration)) < 1e-6
            if product_id not in sol:
                sol[product_id] = list()
            sol[product_id].append((route_No, equ_name, float(start), float(end)))
        for product in products:
            assert product.product_id in sol
        machine_dict = dict()
        machine_type_dict = dict()
        for machine in machines:
            machine_dict[machine.equip_name] = list()
            machine_type_dict[machine.equip_name] = machine.equip_type
        for product in products:
            product_id = product.product_id
            route = None
            for i in range(len(routes)):
                if routes[i].route_id == product.route_id:
                    route = routes[i]
                    break
            for i in range(len(route.route_nums)):
                step = route.route_nums[i]
                tmp_list = list()
                for j in range(len(sol[product_id])):
                    if sol[product_id][j][0] == step:
                        tmp_list.append(j)
                if route.units[i] == '批':
                    assert len(tmp_list) == 1, product_id + ' ' + step + ' ' + str(len(tmp_list))
                elif route.units[i] == '节':
                    assert len(tmp_list) == product.section_num, product_id + ' ' + step + ' ' + str(len(tmp_list))
                else:
                    raise NotImplementError
                for j in range(len(tmp_list)):
                    info = sol[product_id][tmp_list[j]]
                    assert machine_type_dict[info[1]] == route.equip_types[i]
                    machine_dict[info[1]].append((info[2], info[3], product_id))
                    assert info[3] - info[2] <= route.cost_time_high[i] / 60 + 1e-6, \
                        str(info[3]) + ' ' + str(info[2]) + ' ' + str(route.cost_time_high[i] / 60)
                    assert info[3] - info[2] >= route.cost_time_low[i] / 60 - 1e-6, \
                        str(info[3]) + ' ' + str(info[2]) + ' ' + str(route.cost_time_low[i] / 60)
            sol[product_id].sort(key=lambda x: int(x[0]))
            for i in range(1, len(sol[product_id])):
                machine_id = sol[product_id][i][1]
                if machine_type_dict[machine_id] in ['T-02']:
                    assert abs(sol[product_id][i][2] - sol[product_id][i - 1][3]) < 1e-6
        for machine_id in machine_dict:
            tmp = machine_dict[machine_id]
            tmp.sort(key=lambda x: x[0])
            for i in range(1, len(tmp)):
                assert tmp[i][0] >= tmp[i - 1][1], machine_id + ' ' + str(i)
                if machine_type_dict[machine_id] in ['T-03', 'T-04'] and tmp[i][2] != tmp[i - 1][2]:
                    assert tmp[i][0] >= tmp[i - 1][1] + 0.5, \
                        machine_id + ' ' + machine_type_dict[machine_id] + ' ' + tmp[i][2] + ' ' + tmp[i - 1][2]
    
    def score(self, sol_path='data/lx_sol.csv'):
        products = self.data.products
        machines = self.data.equips
        routes = self.data.routes
        f = open(sol_path, 'r', encoding='utf-8')
        sol = dict()
        final_time = 0
        work_time = 0
        t2_finish_time = 0
        t2_start_time = 1000000
        for line in f.readlines()[1:]:
            product_id, route_No, equ_name, start, duration, end = line.split(',')
            if product_id not in sol:
                sol[product_id] = list()
            sol[product_id].append((route_No, equ_name, float(start), float(end)))
            if equ_name == 'Y-2045':
                work_time += float(end) - float(start)
                t2_finish_time = max(t2_finish_time, float(end))
                t2_start_time = min(t2_start_time, float(start))
            final_time = max(final_time, float(end))
        print('score:', format(work_time / final_time * 100, '.2f'), 'total time:', final_time)
        machine_dict = dict()
        machine_type_dict = dict()
        for machine in machines:
            machine_dict[machine.equip_name] = list()
            machine_type_dict[machine.equip_name] = machine.equip_type
        for product in products:
            product_id = product.product_id
            route = None
            for i in range(len(routes)):
                if routes[i].route_id == product.route_id:
                    route = routes[i]
                    break
            for i in range(len(route.route_nums)):
                step = route.route_nums[i]
                tmp_list = list()
                for j in range(len(sol[product_id])):
                    if sol[product_id][j][0] == step:
                        tmp_list.append(j)
                for j in range(len(tmp_list)):
                    info = sol[product_id][tmp_list[j]]
                    machine_dict[info[1]].append((info[2], info[3], product_id))
            sol[product_id].sort(key=lambda x: int(x[0]))
            for i in range(1, len(sol[product_id])):
                machine_id = sol[product_id][i][1]
        for machine_id in machine_dict:
            tmp = machine_dict[machine_id]
            tmp.sort(key=lambda x: x[0])
            work_time = 0
            finish_time = 0
            start_time = 1000000
            for i in range(len(tmp)):
                work_time += tmp[i][1] - tmp[i][0]
                finish_time = max(finish_time, tmp[i][1])
                start_time = min(start_time, tmp[i][1])
            print(machine_id, ':', format(work_time / final_time * 100, '.2f') + '%', 'start_time:', format(start_time, '.2f'), \
                  'end_time:', format(finish_time, '.2f'), 'work_time:', format(work_time, '.2f'))


if __name__ == '__main__':
    verifier = Verifier()
